package com.CRApp.controller;

import com.CRApp.pojo.Result;
import com.CRApp.pojo.User;
import com.CRApp.service.UserService;
import com.CRApp.utils.JwtUtil;
import com.CRApp.utils.Md5Util;
import com.CRApp.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jackson.JsonComponentModule;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.UUID;

/**
 * @ClassName: UserContorller
 * @Author : LuoFan洛樊
 * @Date : 2025/1/30 - 21:42
 * Description : TODO
 */
@RestController
@RequestMapping("/user")
@Validated
public class UserContorller {

    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private JsonComponentModule jsonComponentModule;

    @Autowired
    private FileUploadController fileUploadController;  // 注入 FileUploadController

    //注册
    @PostMapping("/register")
    public Result register(@RequestBody Map<String, String> registerForm){
        String username = registerForm.get("username");
        String password = registerForm.get("password");
        String repassword = registerForm.get("repassword");
        String nickname = registerForm.get("nickname");
        String email = registerForm.get("email");
        
        // 参数校验
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password) 
            || !StringUtils.hasLength(repassword)) {
            return Result.error("用户名或密码不能为空");
        }

        // 用户名格式校验
        if (!username.matches("^[a-zA-Z0-9_]{5,16}$")) {
            return Result.error("用户名必须包含字母、数字或下划线，长度在5到16个字符之间");
        }

        // 密码格式校验
        if (!password.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[A-Za-z\\d]{8,16}$")) {
            return Result.error("密码必须包含大小写字母和数字，长度在8到16个字符之间");
        }

        // 确认密码校验
        if (!password.equals(repassword)) {
            return Result.error("两次输入的密码不一致");
        }

        // 查询用户是否存在
        User u = userService.findByUserName(username);
        if (u != null){
            return Result.error("用户名已存在");
        }

        // 创建用户对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setNickname(nickname);
        user.setEmail(email);
        
        // 注册用户
        userService.register(user);
        return Result.success("注册成功");
    }

    //登录
    @PostMapping("/login")
    public Result login(@RequestBody Map<String, String> loginForm){
        String username = loginForm.get("userName");  // 注意这里是userName
        String password = loginForm.get("password");
        
        if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {
            return Result.error("用户名或密码不能为空");
        }
        
        //查询用户是否存在
        User loginUser = userService.findByUserName(username);
        if (loginUser == null){
            return Result.error("该用户不存在，请检查用户名是否正确！");
        }else {
            if (Md5Util.getMD5String(password).equals(loginUser.getPassword())){
                Map<String, Object> claims = new HashMap<>();
                claims.put("id",loginUser.getId());
                claims.put("username",username);
                String token = JwtUtil.genToken(claims);
                //把token存储到redis中
                redisTemplate.opsForValue().set(token,token,12, TimeUnit.HOURS);
                
                // 创建返回的数据对象
                Map<String, Object> data = new HashMap<>();
                data.put("token", token);
                data.put("user", loginUser);
                
                return Result.success(data);
            }else {
                return Result.error("密码错误！");
            }
        }
    }

    //获取用户信息
    @GetMapping("/userInfo")
    public Result<User> getUserInfo(/*@RequestHeader(name = "Authorization") String token*/){
        //根据用户名查询用户信息
//        Map<String, Object> map = JwtUtil.parseToken(token);
//        String username = (String) map.get("username");

        Map<String,Object> map = ThreadLocalUtil.get();
        String username = (String)map.get("username");
        System.out.println(map);

        User user = userService.findByUserName(username);
        return Result.success(user);
    }

    //修改用户信息
    @PutMapping("/updateUserInfo")
    public Result updateUserInfo(@RequestBody @Validated User user){
        //修改用户信息
        userService.updateUserInfo(user);
        return Result.success();
    }

    //修改用户头像
    @PostMapping("/updateUserPic")
    public Result updateUserPic(@RequestParam("file") MultipartFile file) throws Exception {
        // 1. 检查文件是否为空
        if (file.isEmpty()) {
            return Result.error("请选择要上传的图片");
        }

        // 2. 检查文件大小（10MB = 10 * 1024 * 1024 bytes）
        long maxSize = 10 * 1024 * 1024;
        if (file.getSize() > maxSize) {
            return Result.error("图片大小不能超过10MB");
        }

        // 3. 检查文件格式
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            return Result.error("文件名不能为空");
        }
        
        // 获取文件后缀名并转换为小写
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
        // 允许的图片格式
        String[] allowedFormats = {"jpg", "jpeg", "png", "gif"};
        boolean isValidFormat = false;
        for (String format : allowedFormats) {
            if (format.equals(suffix)) {
                isValidFormat = true;
                break;
            }
        }
        if (!isValidFormat) {
            return Result.error("只支持jpg、jpeg、png、gif格式的图片");
        }

        // 上传文件到阿里云OSS
        Result<String> uploadResult = fileUploadController.upload(file);
        String url = uploadResult.getData();
        
        // 修改用户头像信息
        userService.updateUserPic(url);
        
        return Result.success(url);
    }

    //修改用户密码
    @PatchMapping("/updatePassword")
    public Result updatePassword(@RequestBody Map<String,String> params){
        //校验参数
        String oldPwd = params.get("oldPwd");
        String newPwd = params.get("newPwd");
        String rePwd = params.get("rePwd");

        if(!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)){
            return Result.error("参数不能为空");
        }

        // 使用正则表达式校验新密码
        String passwordPattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[A-Za-z\\d]{8,16}$";
        if (!newPwd.matches(passwordPattern)) {
            return Result.error("新密码格式不正确，必须包含大写字母、小写字母和数字，长度在8到16个字符之间");
        }

        try {
            //获取当前登录用户
            Map<String,Object> map = ThreadLocalUtil.get();
            String username = (String)map.get("username");
            User loginUser = userService.findByUserName(username);
            
            //校验旧密码
            String oldPwdMD5 = Md5Util.getMD5String(oldPwd);
            if(!loginUser.getPassword().equals(oldPwdMD5)){
                return Result.error("原密码错误");
            }

            //校验新密码和确认密码
            if(!newPwd.equals(rePwd)){
                return Result.error("两次输入的密码不一致");
            }

            //更新密码 - 这里传入未加密的密码，让 Service 层去加密
            userService.updataPWD(newPwd);  // 传入未加密的新密码
            
            return Result.success("密码修改成功");
        } catch (Exception e) {
            return Result.error("密码修改失败：" + e.getMessage());
        }
    }

}
